using System;

namespace Aks.Deployment.SharePoint.Data
{
	/// <summary>
	/// Represents a CAML comparison node.
	/// </summary>
	internal class CamlComparison : CamlNode
	{
		/// <summary>CAML where clause comparison format. Arguments include: (0) left part of comparison, (1) equality check, (2) right part of comparison.</summary>
		private const string CamlFormat = @"<{1}>{0}{2}</{1}>";


		/// <summary>
		/// Initializes a new instance of the <see cref="CamlComparison"/> class.
		/// </summary>
		/// <param name="left">The left side of the comparison.</param>
		/// <param name="comparison">The comparison type.</param>
		/// <param name="right">The right side of the comparison.</param>
		public CamlComparison(CamlNode left, CamlComparisonType comparison, CamlNode right)
		{
			Left = left;
			Comparison = comparison;
			Right = right;
		}


		/// <summary>
		/// Gets or sets the left side of the comparison.
		/// </summary>
		/// <value>The left side of the comparison.</value>
		public CamlNode Left { get; set; }


		/// <summary>
		/// Gets or sets the comparison type.
		/// </summary>
		/// <value>The comparison type.</value>
		public CamlComparisonType Comparison { get; set; }


		/// <summary>
		/// Gets or sets the right side of the comparison.
		/// </summary>
		/// <value>The right side of the comparison.</value>
		public CamlNode Right { get; set; }


		/// <summary>
		/// Returns a string that represents the current CAML node.
		/// </summary>
		/// <returns>A string representation of the CAML node.</returns>
		public override string ToCaml()
		{
			return (Left == null || Right == null) ? null : String.Format(CamlFormat, Left.ToCaml(), Comparison.ToCaml(), this.Right.ToCaml());
		}


		#region | Field == (value) |

		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <see cref="CamlBooleanValue"/> that is <c>true</c>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldIsTrue(string field)
		{
			return FieldEqualToValue(field, true);
		}


		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is equal to
		/// the specified <paramref name="value"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="value">The value.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldEqualToValue(string field, bool value)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.EqualTo, new CamlBooleanValue(value));
		}


		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is equal to
		/// the specified <paramref name="value"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="value">The value.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldEqualToValue(string field, int value)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.EqualTo, new CamlIntValue(value));
		}


		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is equal to
		/// the specified <paramref name="value"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="value">The value.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldEqualToValue(string field, string value)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.EqualTo, new CamlTextValue(value));
		}


		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is equal to
		/// the specified choice <paramref name="value"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="value">The value.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldEqualToChoiceValue(string field, string value)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.EqualTo, new CamlChoiceValue(value));
		}


		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is equal to
		/// the specified lookup <paramref name="value"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="value">The value.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldEqualToLookupValue(string field, string value)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.EqualTo, new CamlLookupValue(value));
		}


		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is equal to
		/// the specified <paramref name="userName"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="userName">Name of the user.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldEqualToUserName(string field, string userName)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.EqualTo, new CamlUserValue(userName));
		}

		#endregion


		#region | Field != (value) |

		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is not 
		/// equal to the specified <paramref name="value"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="value">The value.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldNotEqualToValue(string field, string value)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.NotEqualTo, new CamlTextValue(value));
		}


		/// <summary>
		/// Returns a <see cref="CamlComparison"/> instance that represents a <paramref name="field"/> that is equal to
		/// the specified lookup <paramref name="value"/>.
		/// </summary>
		/// <param name="field">The field.</param>
		/// <param name="value">The value.</param>
		/// <returns>A CAML comparison instance.</returns>
		public static CamlComparison FieldNotEqualToLookupValue(string field, string value)
		{
			return new CamlComparison(new CamlField(field), CamlComparisonType.NotEqualTo, new CamlLookupValue(value));
		}

		#endregion
	}
}